﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using Xceed.Silverlight.DataGrid.Converters;
using Xceed.Silverlight.DataGrid.Utils;

namespace Xceed.Silverlight.DataGrid
{
  internal abstract class CellContentElementManager<TOwner> : CellContentElementManagerBase where TOwner : Cell
  {
    #region Static Fields

    private static readonly HorizontalAlignmentToTextAlignmentConverter HorizontalAlignmentToTextAlignmentConverter = new HorizontalAlignmentToTextAlignmentConverter();

    #endregion

    #region Constructor

    protected CellContentElementManager( TOwner owner )
    {
      if( owner == null )
        throw new ArgumentNullException( "owner" );

      m_owner = owner;
    }

    #endregion

    #region Owner Protected Property

    protected TOwner Owner
    {
      get
      {
        return m_owner;
      }
    }

    private readonly TOwner m_owner;

    #endregion

    protected override void OnUpdateTargetBinding( FrameworkElement container )
    {
      if( !( container is Selector ) )
        return;

      DependencyProperty contentProperty;
      if( !this.TryGetContentTargetProperty( container, out contentProperty ) )
        return;

      BindingExpression bindingExpression = container.ReadLocalValue( contentProperty ) as BindingExpression;
      if( ( bindingExpression == null ) || ( bindingExpression.DataItem != m_owner ) )
        return;

      container.SetBinding( contentProperty, bindingExpression.ParentBinding );
    }

    protected override bool TryGetContentSourceBinding( 
      FrameworkElement container, 
      DependencyProperty targetProperty, 
      out Binding binding )
    {
      binding = this.CreateBinding(
                  ReflectionHelper.GetPropertyOrFieldName( () => m_owner.Content ),
                  BindingMode.TwoWay );

      return ( binding != null );
    }

    protected override bool TryGetForegroundSourceBinding( 
      FrameworkElement container, 
      DependencyProperty targetProperty, 
      out Binding binding )
    {
      binding = this.CreateBinding(
                  ReflectionHelper.GetPropertyOrFieldName( () => m_owner.Foreground ) );

      return ( binding != null );
    }

    protected override bool TryGetFontFamilySourceBinding( 
      FrameworkElement container, 
      DependencyProperty targetProperty, 
      out Binding binding )
    {
      binding = this.CreateBinding(
                  ReflectionHelper.GetPropertyOrFieldName( () => m_owner.FontFamily ) );

      return ( binding != null );
    }

    protected override bool TryGetFontSizeSourceBinding( 
      FrameworkElement container, 
      DependencyProperty targetProperty, 
      out Binding binding )
    {
      binding = this.CreateBinding(
                  ReflectionHelper.GetPropertyOrFieldName( () => m_owner.FontSize ) );

      return ( binding != null );
    }

    protected override bool TryGetFontStretchSourceBinding( 
      FrameworkElement container, 
      DependencyProperty targetProperty, 
      out Binding binding )
    {
      binding = this.CreateBinding(
                  ReflectionHelper.GetPropertyOrFieldName( () => m_owner.FontStretch ) );

      return ( binding != null );
    }

    protected override bool TryGetFontStyleSourceBinding( 
      FrameworkElement container, 
      DependencyProperty targetProperty, 
      out Binding binding )
    {
      binding = this.CreateBinding(
                  ReflectionHelper.GetPropertyOrFieldName( () => m_owner.FontStyle ) );

      return ( binding != null );
    }

    protected override bool TryGetFontWeightSourceBinding( 
      FrameworkElement container, 
      DependencyProperty targetProperty, 
      out Binding binding )
    {
      binding = this.CreateBinding(
                  ReflectionHelper.GetPropertyOrFieldName( () => m_owner.FontWeight ) );

      return ( binding != null );
    }

    protected override bool TryGetHorizontalContentAlignmentSourceBinding( 
      FrameworkElement container, 
      DependencyProperty targetProperty, 
      out Binding binding )
    {
      IValueConverter converter = null;
      if( targetProperty == TextBlock.TextAlignmentProperty )
      {
        converter = CellContentElementManager<TOwner>.HorizontalAlignmentToTextAlignmentConverter;
      }

      binding = this.CreateBinding(
                  ReflectionHelper.GetPropertyOrFieldName( () => m_owner.HorizontalContentAlignment ),
                  converter );

      return ( binding != null );
    }

    protected override bool TryGetVerticalContentAlignmentSourceBinding( 
      FrameworkElement container, 
      DependencyProperty targetProperty, 
      out Binding binding )
    {
      binding = this.CreateBinding(
                  ReflectionHelper.GetPropertyOrFieldName( () => m_owner.VerticalContentAlignment ) );

      return ( binding != null );
    }

    protected Binding CreateBinding( string path, BindingMode mode = BindingMode.OneWay )
    {
      return this.CreateBinding( path, null, mode );
    }

    protected Binding CreateBinding( string path, IValueConverter converter, BindingMode mode = BindingMode.OneWay )
    {
      return new Binding( path )
      {
        Converter = converter,
        Mode = mode,
        Source = m_owner
      };
    }
  }
}
